SELECT 
  products_categories.product_id, 
  GROUP_CONCAT(
    IF(
      products_categories.link_type = "M", 
      CONCAT(
        products_categories.category_id, 
        "M"
      ), 
      products_categories.category_id
    )
  ) AS category_ids 
FROM 
  products_categories 
  INNER JOIN categories ON categories.category_id = products_categories.category_id 
  AND categories.storefront_id IN (0, 1) 
  AND (
    categories.usergroup_ids = '' 
    OR FIND_IN_SET(0, categories.usergroup_ids) 
    OR FIND_IN_SET(1, categories.usergroup_ids)
  ) 
  AND categories.status IN ('A', 'H') 
WHERE 
  products_categories.product_id IN (
    356162, 357463, 357496, 357507, 358017, 
    358776, 358802, 360118, 360154, 360656, 
    361435, 364064, 365943, 365961, 365971, 
    366731, 366746, 369904, 369931, 370671, 
    370674, 370697, 375936, 377816
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00230

JSON explain

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "39.91"
    },
    "grouping_operation": {
      "using_filesort": false,
      "nested_loop": [
        {
          "table": {
            "table_name": "products_categories",
            "access_type": "range",
            "possible_keys": [
              "PRIMARY",
              "link_type",
              "pt"
            ],
            "key": "pt",
            "used_key_parts": [
              "product_id"
            ],
            "key_length": "3",
            "rows_examined_per_scan": 72,
            "rows_produced_per_join": 72,
            "filtered": "100.00",
            "using_index": true,
            "cost_info": {
              "read_cost": "7.51",
              "eval_cost": "7.20",
              "prefix_cost": "14.71",
              "data_read_per_join": "1K"
            },
            "used_columns": [
              "product_id",
              "category_id",
              "link_type"
            ],
            "attached_condition": "(`goimagine`.`products_categories`.`product_id` in (356162,357463,357496,357507,358017,358776,358802,360118,360154,360656,361435,364064,365943,365961,365971,366731,366746,369904,369931,370671,370674,370697,375936,377816))"
          }
        },
        {
          "table": {
            "table_name": "categories",
            "access_type": "eq_ref",
            "possible_keys": [
              "PRIMARY",
              "c_status",
              "p_category_id"
            ],
            "key": "PRIMARY",
            "used_key_parts": [
              "category_id"
            ],
            "key_length": "3",
            "ref": [
              "goimagine.products_categories.category_id"
            ],
            "rows_examined_per_scan": 1,
            "rows_produced_per_join": 3,
            "filtered": "5.00",
            "cost_info": {
              "read_cost": "18.00",
              "eval_cost": "0.36",
              "prefix_cost": "39.91",
              "data_read_per_join": "9K"
            },
            "used_columns": [
              "category_id",
              "usergroup_ids",
              "status",
              "storefront_id"
            ],
            "attached_condition": "((`goimagine`.`categories`.`storefront_id` in (0,1)) and ((`goimagine`.`categories`.`usergroup_ids` = '') or (0 <> find_in_set(0,`goimagine`.`categories`.`usergroup_ids`)) or (0 <> find_in_set(1,`goimagine`.`categories`.`usergroup_ids`))) and (`goimagine`.`categories`.`status` in ('A','H')))"
          }
        }
      ]
    }
  }
}

Result

product_id category_ids
356162 20,17421,3M
357463 20,17421,3M
357496 6649,17422,3M
357507 20,17421,3M
358017 20,17421,3M
358776 20,17421,3M
358802 20,17421,3M
360118 6649,17422,3M
360154 20,17421,3M
360656 20,17421,3M
361435 20,17421,3M
364064 20,17421,3M
365943 20,17421,3M
365961 20,17421,3M
365971 20,17421,3M
366731 20,17421,3M
366746 20,17421,3M
369904 20,17421,3M
369931 20,17421,3M
370671 6649,17422,3M
370674 20,17421,3M
370697 20,17421,3M
375936 20,17421,3M
377816 20,17421,3M