lcd.print and sprintf compatiblity??

I think you'll find that one of the calls you make is importing (linking) an incompatible or broken dtostrf which is then breaking the other call you make. The fact that you are only calling sprintf with %d doesn't matter; if the sprintf you import has support for %f then it may bring in a dtostrf or similar. Similarly, the LiquidCrystal::put(float) method will import a dtostrf and other conversion which might break your sprintf.

sprintf is an abomination that shouldn't really be used in microcontroller. It's expensive in both time (it has to parse the format string on every call!) and space (lots of code to support all the format options you'll never use), and it's very error-prone which is not something you want in an embedded application.

You're better off manually calling dtostrf yourself if you want to print out floats. Here's an unrelated snippet of code that I use to fill in some fairly complex numbers on an LCD; you can see it manually inserts a sign, uses dtostrf twice and keeps track of the total length (used) of string so generated in order to fit it into the LCD and overwrite any old content with spaces.

void Program::Exposure::displayTime(LiquidCrystal &disp, bool lin)
{
    disp.setCursor(0,1);

    // print stops
    char used=0;
    if(stops >= 0){
        disp.print("+");
        ++used;
    }
    dtostrf(0.01f*stops, 0, 2, dispbuf);
    used+=strlen(dispbuf);
    disp.print(dispbuf);

    // print compiled seconds
    if(lin){
        disp.print("=");
        dtostrf(0.001f*ms, 0, 3, dispbuf);
        used+=strlen(dispbuf)+2;
        disp.print(dispbuf);
        disp.print("s");
     
        // fill out to 15 chars with spaces
        // keep the 16th for 'D' drydown-indicator
        for(int i=0;i<15-used;++i)
            dispbuf[i]=' ';
        dispbuf[15-used]='\0';
        disp.print(dispbuf);
    }  
}