Change query_posts to WP_Query in page but does not work

There should be no reason why you should get results with query_posts and not with WP_Query. query_posts uses WP_Query, so both should work the same.

Your code is really messy and you are using miltiple syntaxes which makes your code hard to debug. This leads hiding obvious bugs and really send you on unnecessary wild goose chases. Also, it is not necessary to set arguments with its default values.

Lets rewrite your code to something more readable and more reliable.

/**
 * Set the query arguments we will use to get posts by
 * Since PHP 5.4 we can use short array syntax, so we can use []
 * instead of array(). You should be on PHP 5.6 already and should not 
 * be using any version prior to 5.6
 */
$args = [ 
    'posts_per_page'   => 24,
    'suppress_filters' => true, // Do not let filters change the query
    'tax_query'        => [
        [ // Removed the relation as AND is default value
            'taxonomy' => 'category',
            'terms'    => 'uncategorized',
            'field'    => 'slug'
        ],
        [
            'taxonomy' => 'creatives-content-types',
            'terms'    => 'newsfeed',
            'field'    => 'slug'
        ]
    ]
];
$custom_query = new WP_Query($args);

if ( $custom_query->have_posts() ) { // Always first make sure you have posts to avoid bugs
    $count = 0;

    $html_col_o  = '<div>';
    $html_col_t="<div>";
    $html_col_th="<div>";

    while ( $custom_query->have_posts() ) {
        $custom_query->the_post();

        $count++;
        $image     = get_field( 'featured_image', get_the_ID() ); // Use get_the_ID() for reliability

        if ( $image ) { //Make sure we have an image to avoid bugs or unexpected output
            $size="large";           
            $image_url = $image['sizes'][$size];

            $description = '<h2>' . get_the_title() . '</h2>' . get_field( 'description', get_the_ID() ); // Again, use get_the_ID()

            if( $count%3 == 1 ) {
                $html_col_o  = $html_col_o  . '<img src="' . $image_url . '" id="img-' . $count . '" data-count="' . $count . '" data-description="' . $description . '"/>';
            } elseif( $count%3 == 2 ) {
                $html_col_t  = $html_col_t  . '<img src="' . $image_url . '" id="img-' . $count . '" data-count="' . $count . '" data-description="' . $description . '"/>';
            } elseif( $count%3 == 0 ) {
                $html_col_th = $html_col_th . '<img src="' . $image_url . '" id="img-' . $count . '" data-count="' . $count . '" data-description="' . $description . '"/>';
            }

        }
    }

    $html_col_o  = $html_col_o  . '</div>';
    $html_col_t  = $html_col_t  . '</div>';
    $html_col_th = $html_col_th . '</div>';

    echo $html_col_o . $html_col_t . $html_col_th;

    wp_reset_postdata(); // VERY VERY IMPORTANT, restes the $post global back to the main query
}

You can now do echo $custom_query->request to inspect the generated SQL query, alternatively, you can do var_dump( $custom_query ) to inspect the complete query object. You should also turn debug on and look for obvious bugs.

But as I said, there should be no reason why query_posts works and WP_Query not