I tend to think in terms of features:
Syntax:
C-Based or what-have-you. Java has a C-based syntax. I highly recommend trying out something like Python or Ruby to get your head out of the syntax and thinking more in terms of fundamentals of how a given language works. I'm of the opinion that no syntax needs to get bulkier than C-based and have no problem building blocks around white-space.
Compiled vs. interpreted w. Build-Process vs. Interpreted/Console:
I have very little familiarity with compile time vs. run-time environment concerns but I get that there's a whole bag of concerns there that I rarely think about.
Likewise there are plenty of interpreted languages that still have something of a compile-ish process for running inside a virtual machine like Java does. You still have to rebuild to see changes to things.
And then there's JavaScript and Python which you can execute on the fly, command by command in a console in a live environment. All three can lead to very different ways of writing code.
Dynamic vs. Strict typing:
I tend to see the two as design tradeoffs. When you are at a much lower level and performance is critical, static typing makes a lot of sense. I've never understood this notion of one being "safer" than another somehow but I came up in a very plastic/dynamic language where you just learn how the typing system works and what to expect, basically. Type shenanigans are rarely a concern for me in JS. In some ways the flexibility can make things more robust, although admittedly a touch more arcane for a more Jr. level dev if you don't know about some of the pot-holes in the language.
Block-Level Scope vs. Function Scope vs. ?:
Block-Level is the most common (anything between {} in most c-based syntax languages). JavaScript scope is built around functions (which are also used to build objects so effectively objects too). There's also a great deal variation in what kind of access you have from inner scope to an outer-scope. I'm not familiar with other scoping schemes but I'm sure they exist.
Classical OOP vs. Prototypal OOP vs Almost-OOP(structs in C?) vs Non-OOP:
Even in class-based OOP there is a great deal of room for variation. Whether you can do multiple inheritance (ew, well in excess, ew), define interfaces, etc...
In JavaScript we have a sort of stunted hybrid prototypal OOP where objects are considerably more simple, highly mutable, but we still have the ability to separate interface from internal concerns, which IMO, is the important aspect of encapsulation.
The thing about OOP is that there really is a lot of stuff you can pull off that is essentially OOP-oriented without technically being OOP. There are purists of course but at the end of the day, Design Patterns are about achieving certain abstractions that work well in certain situations. Don't be too quick to assume ideas from an OOP-based language have no use in something that's more procedurally-oriented. And I'm not talking about JavaScript. It's not at all limited by its goofy version of a prototype based OOP paradigm.
First-Class Functions:
Not having these in a language is a hard thing for me to give up. You can pass functions around like they were data for use in other contexts. This makes event handling schemes in particular very easy to implement but it also makes it very easy to adapt the language to work the way you'd like it to. It is, more than anything I suspect, the thing that has made JavaScript the success that it ultimate has been in spite of being designed in two weeks and getting Java-approximate syntax slapped on to it as a marketing scheme.
Closures:
I'm not sure where the debate is at for Java, but I know a lot of Java devs were clamoring for this feature a year or two ago. In a non-closure language, when a function closes, anything that is somehow able to reference stuff from inside that function won't be able to access it because it was garbage collected. In a closure, execution context is bound such that if you're able to reference stuff inside that closed function from another scope like in a returned object or function you basically get those vars as they were when the function closed. It's like a jamming your foot in the door of garbage collection, although I suspect it's implemented more like copies of those vars made into local vars of the referring entity.
Rigid/Strict/Safe vs. Giving You all The Rope You Want:
JS devs and Java devs tend to not understand each other at all and I think it has a lot to do with the two languages falling on near-opposite sides of this particular design spectrum. I don't want you to protect me from myself or from the other devs on my team. I want to do a lot more in a lot less code and to do it all in very different (but consistent for a given domain) ways depending on the situation. There are absolutely tradeoffs to both and a lot of languages tend to fall more in the middle.