Foreach issue in get_posts function

The issue is that in the beginning of each loop you reset $output to an empty string:

$output="";

So when then loop has finished, $output will only contain the output of the last loop.

To fix the issue you’ll just need to move this line outside of the loop, to initialise the variable, while only adding to it with .= inside the loop:

$content_arr = explode( ',', $content);
$output="";

if ( is_array( $content_arr ) && count( $content_arr ) > 0 ) {
    foreach ( $content_arr as $category_name ) {
        $args = array(
            'category_name'  => trim( $category_name ),
            'posts_per_page' => 7,
            'order'          => 'DESC',
            'orderby'        => 'post_date',
        );

        $post_counter = 1;
        $the_query    = new WP_Query( $args );

        if ( $the_query->have_posts() ) : 
            while ( $the_query->have_posts() ) : $the_query->the_post(); 
                if ( has_post_thumbnail() ):
                    //the_post_thumbnail();
                else: 

                endif;

                $output .= '<div class="col-md-4 mb-5">' . get_the_ID() . '-' . get_the_title() . '</div>';

                $post_counter++;
            endwhile;

            $the_query->reset_postdata();

            echo $post_counter . "-";
        endif;