This is a tricky and interesting one. It would be pretty easy to write hardcoded orders for a whitelist of categories, but a true ordering algorithm - which will handle an arbitrary number of categories, and an arbitrary tree depth - requires recursion. What follows probably is not the most efficient solution possible, but it works to order a list of categories of no matter what length or depth:

    $categories = get_the_category();

    // Assemble a tree of category relationships
    // Also re-key the category array for easier
    // reference
    $category_tree = array();
    $keyed_categories = array();

    foreach( (array)$categories as $c ) {
        $category_tree[$c->cat_ID] = $c->category_parent;
        $keyed_categories[$c->cat_ID] = $c;
    }

    // Now loop through and create a tiered list of
    // categories
    $tiered_categories = array();
    $tier = 0;

    // This is the recursive bit
    while ( !empty( $category_tree ) ) {
        $cats_to_unset = array();
        foreach( (array)$category_tree as $cat_id => $cat_parent ) {
            if ( !in_array( $cat_parent, array_keys( $category_tree ) ) ) {
                $tiered_categories[$tier][] = $cat_id;
                $cats_to_unset[] = $cat_id;
            }
        }
        
        foreach( $cats_to_unset as $ctu ) {
            unset( $category_tree[$ctu] );
        }
        $tier++;
    }
    
    // Walk through the tiers to order the cat objects properly
    $ordered_categories = array();
    foreach( (array)$tiered_categories as $tier ) {
        foreach( (array)$tier as $tcat ) {
            $ordered_categories[] = $keyed_categories[$tcat];
        }
    }
    
    // Now you can loop over them and do whatever you want
    foreach( (array)$ordered_categories as $oc ) {
        echo $oc->cat_name . ' ';
    }

Note that, if `get_the_category()` returns multiple categories with the same parent, this algorithm treats them the same (which is to say that they are placed in the same order in which `get_the_category()` returns them).