C single-linked list with remove
No need to peek ahead for the loop condition. Especially not AFTER incrementing it already. Coincidence that this function was not part of the test suite?

void printList(node* head)
{
  if (head == NULL) return;

  while(head)
  {
    printf("%d, ", head-&gt;val);
    head = head-&gt;next;
  };

  printf("\n");
}




Too much redundant code:

void clean(node* head)
{
  while (head)
  {
    node* curr = head;
    head = head-&gt;next;
    free(curr);
  }
}




In void insert(node* head, int val), no need to branch inside the loop. Do it step by step. First find the tail, then append.



void removeIf(node** head, int val) would become already much simpler if it did just add a temporary head to the list, as the special handling for removing a chain at the head wouldn't be necessary in that case. Finally destroy the temporary head again, and overwrite head unconditionally.



In int size(node* root), why call it root all of a sudden and no longer head?

Also, unnecessary lookahead and branching again:

int size(node* head)
{
  int sz = 0;
  while (head)
  {
    ++sz;
    head = head-&gt;next;
  }
  return sz;
}




In terms of code style only one remark, and that is on the location of the * when working with pointer types.

I know, placing it next to the type feels more natural, but it's semantically inaccurate, and it will trip you the first time you attempt to declare multiple variables at once. Placing it where there compiler would sort it helps preventing these mistakes.