You should simply be able to add another foreach loop, using the get_term_children() function.
Change your lines:
foreach( $tags as $tag ) {
$name = apply_filters( 'the_title', $tag->name );
$list .= '<li><a href="' . get_term_link( $tag ) . '" title="' . sprintf(__('View all posts tagged with %s', ''), $tag->name) . '">' . $tag->name . ' </a></li>';
}
…to…
foreach( $tags as $tag ) {
$name = apply_filters( 'the_title', $tag->name );
$list .= '<li><a href="' . get_term_link( $tag ) . '" title="' . sprintf(__('View all posts tagged with %s', ''), $tag->name) . '">' . $tag->name . ' </a>';
// show children in their own ul
if($children = get_term_children($tag->ID, 'type')) {
$list .= '<ul>';
foreach($children as $child) {
$list .= '<li><a href="' . get_term_link( $child ) . '" title="' . sprintf(__('View all posts tagged with %s', ''), $child->name) . '">' . $tag->name . ' </a></li>';
}
$list .= '</ul>';
}
// close li after this one
$list .= '</li>';
}
(untested)
You could make this method far more beautiful if you would do it recursive 😉 But I think this should do.