wp_trash_post() duplicates post to trash

As the function name suggests, wp_trash_post() only trashes a post. If you want to have a post completely deleted then you can use wp_delete_post( int $postid, bool $force_delete = false ) instead.

https://developer.wordpress.org/reference/functions/wp_delete_post/

When the post and page is permanently deleted, everything that is tied
to it is deleted also. This includes comments, post meta fields, and
terms associated with the post.

The post or page is moved to trash instead of permanently deleted
unless trash is disabled, item is already in the trash, or
$force_delete is true.


EDIT 14.11.2019

Perhaps WP just freaks out, because you’re using wp_trash_post for the same $post_id on every iteration of the while loop. Maybe you could test one of the following functions, which I wrote based on your code, depending on whether you want to delete single or all matched posts.

function run_every_five_minutes_delete_one_matched_post() {
  global $post;
  if ( empty($post->ID) ) {
    return;
  }
  $wp_query = new WP_Query(
    array(
      'p'                      => $post->ID, // query only for this particular post
      'date_query'             => array(
        'after'                => '2 hours ago', 
        'inclusive'            => true
      ),
      'no_found_rows'          => true,
      'update_post_meta_cache' => false,
      'update_post_term_cache' => false,
      'fields'                 => 'ids' // no need to query all of the post data
    )
  );
  if ($wp_query->posts) {
    wp_delete_post($post->ID, true); // second parameter true bypasses trash and force deletes the post
  }  
}

function run_every_five_minutes_delete_all_matched_posts() {
  $wp_query = new WP_Query(
    array(
      'cat'                    => array(1), 
      'posts_per_page'         => -1,
      'date_query'             => array(
        'after'                => '2 hours ago', 
        'inclusive'            => true
      ),
      'no_found_rows'          => true,
      'update_post_meta_cache' => false,
      'update_post_term_cache' => false,
      'fields'                 => 'ids'
    )
  );
  if ($wp_query->posts) {
    array_walk($wp_query->posts, function($post_id){
      wp_delete_post($post_id, true); // second parameter true bypasses trash and force deletes the post
    });
  }
}