Updated: Using a custom function hooked in woocommerce_product_query_meta_query
filter hook, targeting non "out of stock" products on shop archive pages only:
add_filter( 'woocommerce_product_query_meta_query', 'shop_only_instock_products', 10, 2 );
function shop_only_instock_products( $meta_query, $query ) {
// Only on shop archive pages
if( is_admin() || is_search() || ! is_shop() ) return $meta_query;
$meta_query[] = array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => '!='
);
return $meta_query;
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works