How to show only related products by subcategory in WooCommerce:

  1. Install this plugin : https://wordpress.org/plugins/code-snippets/
  2. Create a new code snippet
  3. Paste the code and activate it

Work with WooCommerce 3.8.1

add_filter('woocommerce_related_products', 'add_related_products');
function add_related_products($related_product_ids)
{
global $post;

// get the cats this product is in
$terms = get_the_terms($post->ID, 'product_cat');

// if there is only one category jump out.
if (count($terms) === 1) {
return $args;
}

$cats = array();
// remove anything that is a parent cat
foreach ($terms as $k => $term) {
if ($term->parent === 0) {
unset($terms[$k]);
} else {
// build list of terms we do want (children)
$cats[] = $term->term_id;
}
}

$post_ids = get_posts(array(
'post_type' => 'product',
'numberposts' => -1, // get all posts.
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $cats,
),
// Remove current product
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $post->ID,
'operator' => 'NOT IN',
),
),
'fields' => 'ids', // Only get post IDs
));

return $post_ids;
}

References:
https://gist.github.com/deadlyhifi/5b7115d79e610f125a3c
https://stackoverflow.com/questions/26316952/woocommerce-only-show-related-products-from-same-subcategory
https://stackoverflow.com/questions/56705222/woocommerce-output-related-products-args-hook-not-working-as-expected