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 (
    358826, 360105, 360714, 361440, 361448, 
    361978, 361981, 361984, 363297, 363314, 
    364057, 364083, 364116, 365403, 365414, 
    367279, 368052, 368072, 368635, 369359, 
    369937, 369949, 371995, 372011
  ) 
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 (358826,360105,360714,361440,361448,361978,361981,361984,363297,363314,364057,364083,364116,365403,365414,367279,368052,368072,368635,369359,369937,369949,371995,372011))"
          }
        },
        {
          "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
358826 20,17421,3M
360105 6649,17422,3M
360714 20,17421,3M
361440 20,17421,3M
361448 6649,17422,3M
361978 20,17421,3M
361981 6649,17422,3M
361984 20,17421,3M
363297 20,17421,3M
363314 20,17421,3M
364057 20,17421,3M
364083 20,17421,3M
364116 20,17421,3M
365403 20,17421,3M
365414 6649,17422,3M
367279 20,17421,3M
368052 20,17421,3M
368072 20,17421,3M
368635 20,17421,3M
369359 20,17421,3M
369937 20,17421,3M
369949 20,17421,3M
371995 20,17421,3M
372011 20,17421,3M