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 (
    415596, 416111, 416112, 416119, 416129, 
    416142, 416146, 416148, 416866, 416874, 
    416878, 416889, 416897, 416902, 416909, 
    416914, 416916, 416920, 417420, 417422, 
    417432, 417443, 418191, 418194
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00146

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 (415596,416111,416112,416119,416129,416142,416146,416148,416866,416874,416878,416889,416897,416902,416909,416914,416916,416920,417420,417422,417432,417443,418191,418194))"
          }
        },
        {
          "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
415596 20,17421,3M
416111 6649,17422,3M
416112 6649,17422,3M
416119 6649,17422,3M
416129 6649,17422,3M
416142 6649,17422,3M
416146 20,17421,3M
416148 20,17421,3M
416866 6649,17422,3M
416874 6649,17422,3M
416878 6649,17422,3M
416889 6649,17422,3M
416897 6649,17422,3M
416902 6649,17422,3M
416909 20,17421,3M
416914 6649,17422,3M
416916 20,17421,3M
416920 6649,17422,3M
417420 6649,17422,3M
417422 6649,17422,3M
417432 6649,17422,3M
417443 20,17421,3M
418191 6649,17422,3M
418194 6649,17422,3M