SELECT 
  cscart_products_categories.product_id, 
  GROUP_CONCAT(
    IF(
      cscart_products_categories.link_type = "M", 
      CONCAT(
        cscart_products_categories.category_id, 
        "M"
      ), 
      cscart_products_categories.category_id
    )
  ) AS category_ids 
FROM 
  cscart_products_categories 
  INNER JOIN cscart_categories ON cscart_categories.category_id = cscart_products_categories.category_id 
  AND cscart_categories.storefront_id IN (0, 1) 
  AND (
    cscart_categories.usergroup_ids = '' 
    OR FIND_IN_SET(
      0, cscart_categories.usergroup_ids
    ) 
    OR FIND_IN_SET(
      1, cscart_categories.usergroup_ids
    )
  ) 
  AND cscart_categories.status IN ('A', 'H') 
WHERE 
  cscart_products_categories.product_id IN (
    969, 970, 632, 633, 1013, 1014, 1016, 
    1017, 613, 614, 615, 616, 617, 618, 619, 
    620, 622, 636, 637, 972, 973, 974, 975, 
    1030, 621, 1029
  ) 
GROUP BY 
  cscart_products_categories.product_id

Query time 0.00128

JSON explain

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "107.69"
    },
    "grouping_operation": {
      "using_temporary_table": true,
      "using_filesort": true,
      "cost_info": {
        "sort_cost": "3.60"
      },
      "nested_loop": [
        {
          "table": {
            "table_name": "cscart_categories",
            "access_type": "ALL",
            "possible_keys": [
              "PRIMARY",
              "c_status",
              "p_category_id"
            ],
            "rows_examined_per_scan": 125,
            "rows_produced_per_join": 5,
            "filtered": "4.00",
            "cost_info": {
              "read_cost": "29.49",
              "eval_cost": "1.00",
              "prefix_cost": "30.49",
              "data_read_per_join": "20K"
            },
            "used_columns": [
              "category_id",
              "storefront_id",
              "usergroup_ids",
              "status"
            ],
            "attached_condition": "((`cscart`.`cscart_categories`.`storefront_id` in (0,1)) and ((`cscart`.`cscart_categories`.`usergroup_ids` = '') or find_in_set(0,`cscart`.`cscart_categories`.`usergroup_ids`) or find_in_set(1,`cscart`.`cscart_categories`.`usergroup_ids`)) and (`cscart`.`cscart_categories`.`status` in ('A','H')))"
          }
        },
        {
          "table": {
            "table_name": "cscart_products_categories",
            "access_type": "ref",
            "possible_keys": [
              "PRIMARY",
              "pt"
            ],
            "key": "PRIMARY",
            "used_key_parts": [
              "category_id"
            ],
            "key_length": "3",
            "ref": [
              "cscart.cscart_categories.category_id"
            ],
            "rows_examined_per_scan": 12,
            "rows_produced_per_join": 3,
            "filtered": "6.01",
            "index_condition": "(`cscart`.`cscart_products_categories`.`product_id` in (969,970,632,633,1013,1014,1016,1017,613,614,615,616,617,618,619,620,622,636,637,972,973,974,975,1030,621,1029))",
            "cost_info": {
              "read_cost": "61.60",
              "eval_cost": "0.72",
              "prefix_cost": "104.09",
              "data_read_per_join": "57"
            },
            "used_columns": [
              "product_id",
              "category_id",
              "link_type"
            ]
          }
        }
      ]
    }
  }
}

Result

product_id category_ids
613 355,309M,311
614 355,309M,311
615 355,309M,311
616 355,309M,311
617 309M,311,355
618 355,309M,311
619 355,309M,311
620 355,309M,311
621 355,311M
622 355,309M,311
632 345,359,309M
633 309M,345,359
636 309M,310,350
637 309M,310,350
969 349M,309,310
970 349M,309,310
972 350M,309,310
973 309,310,350M
974 350M,309,310
975 350M,309,310
1013 356M,309,345
1014 345,356M,309
1016 345,357M,309
1017 345,357M,309
1029 311M,355
1030 355,309M,311