Ho fatto delle modifiche, e sono (in parte) ritornato sui miei passi sul come creare la lista, per l'inserimento ora dovremmo esserci:
codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10

typedef struct Libro *lista;
typedef struct Libro{
	int ID;
	char Autore[255];
	char Titolo[255];
	char Parole[255];
	lista next;
} Libro;

Libro * nuovoLibro(void);						// Restituisce un puntatore ad un nuovo libro allocato.
void makeMenu(int *select);						// Stampa il menu e acquisice la scelta.
void cercapar(Libro *p, int nLibri, int mod);	// Cerca i libri in base alle parole chiave e modalità.
void destLibri(Libro *p);						// Dealloca tutta la lista.
void stampLibri(Libro *p);						// Stampa la lista completa.
void remLibri(Libro **p, int nLibri);			// Rimuove il libro selezionato dall'elenco.
void add2tail(Libro **p, Libro **new);			// Aggiunge un elemento in coda.
int countlibri(Libro *p);						// Conta gli elementi della lista.

int main(int argc, char *argv)
{
	int select, nLibri=0, mod;
	Libro *inizio = NULL;
	Libro *p;
	
	do{ //cicla fino a quando l'utente decide di terminare.
		makeMenu(&select);
		while (getchar() != '\n');
		
		switch(select){
			case 0: //exit
				break;
			case 1: //alloca libro, lo accoda e aggiorna nLibri
				if(nLibri<SIZE){
					p = nuovoLibro();
					add2tail(&inizio, &p);
					nLibri = countlibri(inizio);
					printf("Libro inserito correttamente(%d/%d).\n", nLibri, SIZE);
				}else
					printf("Lo spazio sugli scaffali della biblioteca è esaurito.\n");
				break;
			case 2: //stampa lista
				if(nLibri!=0)
					stampLibri(inizio);
				else
					printf("Non ci sono libri.\n");
				break;
                        case 5: //rimuove un libro dalla lista, aggiorna nLibri
				if(nLibri!=0){
					remLibri(&inizio, nLibri);
					nLibri = countlibri(inizio);
					printf("Libro rimosso con successo(%d/%d).\n", nLibri, SIZE);
				}else
					printf("Non ci sono libri.\n");
				break;
		}
	}while(select != 0);
	destLibri(inizio);
return 0;
}

Libro * nuovoLibro(void)
{
	Libro *p;
	p= (Libro *) malloc(sizeof(Libro));
	
	printf("Inserire l'ID del libro: ");
	scanf("%d", &p->ID);
	while (getchar() != '\n'); //per pulire il buffer dopo scanf
	printf("Inserire l'Autore: ");
	fgets(p->Autore, 255, stdin);
	printf("Inserire il Titolo: ");
	fgets(p->Titolo, 255, stdin);
	printf("Inserire le 5 parole chiavi, separate da spazi: ");
	fgets(p->Parole, 255, stdin);
	return p;
}

int countlibri(Libro *p)
{
	int i = 1;
	while(p->next != NULL ){
		i++;
		p = p->next;
	}
	return i;
}

void add2tail(Libro **p, Libro **new)
{	
	Libro *inizio = *p;
	if(*p){							//se inizio non è null scorro alla fine della lista
		while((*p)->next) 
			*p = (*p)->next;
		(*p)->next = *new;
		*p = inizio;				//per non perdere l'inizio della lista
	}else							//altrimenti lo metto in testa
		*p = *new;
	
}

void destLibri(Libro *p)
{
	if(p == NULL) 
		return;
	Libro *temp;
	temp = p->next;
	free(p);
	destLibri(temp);
}
Ma ora ho un dubbio:

Riguardo la funzione destLibri (quella che si occupa della deallocazione della lista). In questo caso passo un puntatore singolo alla lista; Sto comunque liberando lo spazio della lista, oppure sto agendo su solamente su copie temportanee? (destLibri la chiamo in fondo, subito dopo il do-while).