You need to first filter on parent category, then after if you got a child category of any parent category, then you need to find out post of that category.
Please try below code and let me know if you have any query:
<?php
$terms = get_terms( array(
'taxonomy' => 'category', //Default category
'hide_empty' => false,
) );
echo "<ul>";
foreach ($terms as $term) {
$parent = $term->parent;
if ( $parent == '0' ) {
/* Parent category */
echo '<li>' . $term->name . '</li>';
/* Child category */
$childrens = get_categories( array ('parent' => $term->term_id ));
echo "<ul>";
foreach($childrens as $children) :
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category', //Default category
'field' => 'slug',
'terms' => $children->slug,
),
),
);
echo '<li>' . $children->name . '</li>';
/* Child category posts */
?>
<ul>
<?
$loop1 = new wp_Query($args);
while($loop1->have_posts()) : $loop1->the_post();
the_title( '<h6>', '</h6>' );
endwhile;
wp_reset_query();
?>
</ul>
<?php
endforeach;
echo "</ul>";
/* Parent category posts */
if (empty($childrens))
{
?>
<ul>
<?
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $term->slug,
),
),
);
$loop = new wp_Query($args);
while($loop->have_posts()) : $loop->the_post();
the_title( '<h6>', '</h6>' );
endwhile;
wp_reset_query();
?>
</ul>
<?php
}
}
}
echo "</ul>";
?>