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 (
    377817, 379144, 379186, 379905, 380474, 
    380489, 380516, 381251, 381274, 381809, 
    381812, 381832, 382569, 383106, 383107, 
    383137, 383875, 383893, 384435, 384452, 
    384464, 384466, 385196, 385200
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00117

JSON explain

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "39.92"
    },
    "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.52",
              "eval_cost": "7.20",
              "prefix_cost": "14.72",
              "data_read_per_join": "1K"
            },
            "used_columns": [
              "product_id",
              "category_id",
              "link_type"
            ],
            "attached_condition": "(`goimagine`.`products_categories`.`product_id` in (377817,379144,379186,379905,380474,380489,380516,381251,381274,381809,381812,381832,382569,383106,383107,383137,383875,383893,384435,384452,384464,384466,385196,385200))"
          }
        },
        {
          "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.92",
              "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
377817 20,17421,3M
379144 20,17421,3M
379186 20,17421,3M
379905 6649,17422,3M
380474 20,17421,3M
380489 20,17421,3M
380516 20,17421,3M
381251 20,17421,3M
381274 20,17421,3M
381809 20,17421,3M
381812 20,17421,3M
381832 20,17421,3M
382569 20,17421,3M
383106 20,17421,3M
383107 20,17421,3M
383137 20,17421,3M
383875 20,17421,3M
383893 20,17421,3M
384435 20,17421,3M
384452 20,17421,3M
384464 6649,17422,3M
384466 20,17421,3M
385196 6649,17422,3M
385200 20,17421,3M