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 (
    323729, 323745, 324475, 324479, 324489, 
    326336, 326389, 327714, 329001, 329002, 
    329026, 330320, 330348, 331082, 331092, 
    331657, 332936, 332946, 332959, 333756, 
    334264, 334281, 334310, 335049
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00136

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 (323729,323745,324475,324479,324489,326336,326389,327714,329001,329002,329026,330320,330348,331082,331092,331657,332936,332946,332959,333756,334264,334281,334310,335049))"
          }
        },
        {
          "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
323729 20,17421,3M
323745 20,17421,3M
324475 20,17421,3M
324479 20,17421,3M
324489 20,17421,3M
326336 20,17421,3M
326389 20,17421,3M
327714 20,17421,3M
329001 20,17421,3M
329002 20,17421,3M
329026 20,17421,3M
330320 20,17421,3M
330348 20,17421,3M
331082 20,17421,3M
331092 20,17421,3M
331657 20,17421,3M
332936 20,17421,3M
332946 20,17421,3M
332959 20,17421,3M
333756 20,17421,3M
334264 20,17421,3M
334281 20,17421,3M
334310 6649,17422,3M
335049 20,17421,3M