Create WP_Query to search for posts by their categories or their parent/child categories

Use get_categories first to get all the post categories to use in the form, then loop through them to display a multicheck input…

function hierarchical_category_inputs ($cat, $indent) {

    $cats = get_categories('hide_empty=false&orderby=name&order=ASC&parent=".$cat);
    $indent++;

    if ($cats) {
        foreach ($cats as $cat) {
           echo "<input type="checkbox' name="cat-".$cat->term_id.""";
           echo " style="margin-left: ".($indent*10)."px;"> ".$cat->name."<br>";
           hierarchical_category_inputs($cat->term_id, $indent);
        }
    }
}  

echo "<form method='post'>";
// 0 for all categories, -1 so first indent is 0
hierarchical_category_inputs(0,-1);
echo "<input type="hidden" name="custom_catsearch" value="yes">";
echo "<input type="submit" value="Search">";
echo "</form>";

Then in the search part you would assemble the array of ticked categories to pass to WP_Query:

function custom_catsearch_output() {
    $cats = array();
    foreach ($_POST as $key => $value) {
        // make sure the post key starts with cat-
        if (substr($key,0,4) == 'cat-') {
            // check for check of the checkbox
            if ($value == '1') {
                // get the cat id from after cat-
                $cats[] = substr($key,4,strlen($key));
            }
        }
    }

    $query = new WP_Query(array('cat' => $cats));

    print_r($query);
    // ... do something different with the results ...

}