date_query in pre_get_posts out of memory

You’re not using pre_get_posts correctly. You’ve called new WP_Query which then runs your hook, which calls new WP_Query, which then runs your hook… and so on. You’re in an infinite loop.

The proper way to use pre_get_posts is to modify the $query parameter using $query->set() to adjust the query. You don’t need to perform a brand new query:

function test_filter( $query ) {
    $options = get_option( 'dh_options' );
    $cats    = array( 54, 55, 56 );

    if ( $options['checkbox_usr_q'] == true ) {
        if ( ! is_admin() && $query->is_main_query() && $query->is_category( $cats ) ) {
            $query->set(
                'date_query',
                array(
                    array(
                        'column'    => 'post_date_gmt',
                        'after'     => 'May 1st, 2021',
                        'inclusive' => true,
                    ),
                )
            );
        }
    }
}

Also note that I changed $query->in_category, which doesn’t exist, to $query->is_category, and I changed the value to an array of IDs. That function does not accept a comma-separated string.