Faits :
A.
A._ a été engagée le 23 mai 2014 par le Service pénitentiaire de B._ en qualité d'agente de détention en formation à 100% au sein de l'établissement xxx, à U._. Le contrat de travail prévoyait une durée maximale de cinq ans. Le salaire mensuel brut était de 6'428 fr.30, payable 13 fois l'an.
Le 21 août 2015, un téléphone portable a été découvert dans l'une des cellules de l'établissement carcéral. Une enquête pénale a été ouverte. L'extraction des données de l'appareil saisi a révélé deux identifiants «Skype» présents dans la mémoire du téléphone, lesquels correspondaient à A._, respectivement à une dénommée D._ [correspondant au prénom de A.] («Dyyy» et «Dzzz»).
Le 17 août 2016, le directeur de l'établissement s'est approché de l'employée de manière informelle afin de lui demander si les identifiants «Skype» décelés lui appartenaient. Les soupçons pesant contre elle ont également été évoqués à cette occasion.
Le 24 août 2016, lors d'un entretien organisé entre le directeur de l'établissement pénitentiaire, le surveillant-chef et A._, cette dernière a reconnu avoir eu des contacts téléphoniques (mode téléphonie et messages) avec une personne détenue. Le procès-verbal de cet entretien a été signé à l'occasion d'une nouvelle rencontre tenue le lendemain.
Par courrier du 26 août 2016, le Service des ressources humaines du Département de la justice, de la sécurité et de la culture a informé l'employée de son intention de mettre fin à son contrat de travail pour les motifs suivants: l'employée avait entretenu, avec un ou des détenus, un lien qui était totalement incompatible avec ses devoirs de service; elle l'avait caché à ses supérieurs pendant près de deux ans, au même titre que la présence d'objets prohibés dans l'enceinte de la prison; elle avait ainsi contrevenu de manière manifeste à son cahier des charges et au code de déontologie et sapé le rapport de confiance qui devait exister entre l'autorité et ses collaborateurs. L'employée était invitée à s'exprimer.
Par lettre du 30 septembre 2016, A._ a contesté le contenu du courrier précédent et les reproches formulés à son encontre. Elle a souligné le contexte et l'ancienneté des faits qui s'étaient déroulés entre septembre et novembre 2014. Par ailleurs, elle a indiqué qu'elle n'avait alors pas conscience d'être en contact «Skype» avec un détenu et que, lorsqu'elle avait pu l'imaginer, elle y avait immédiatement mis fin. Elle a expliqué qu'à l'instar de ses collègues, elle savait qu'un ancien surveillant avait introduit des téléphones portables au sein de l'établissement, qu'elle n'en avait jamais vus, mais qu'elle avait imaginé qu'il était possible qu'un détenu l'ait contactée par ce biais. Il ne pouvait enfin lui être reproché d'avoir contrevenu à son cahier des charges et au code de déontologie dès lors qu'elle n'y avait adhéré qu'après les faits qui lui étaient reprochés.
L'employée s'est trouvée en incapacité de travailler depuis le 25 août 2016.
Par courrier du 25 novembre 2016, alors que l'employée était toujours en arrêt maladie, le service précité a résilié le contrat de travail avec effet au 31 janvier 2017.
Le 23 décembre suivant, A._ a formé opposition au congé, qu'elle tenait pour abusif.
B.
A la suite de l'échec de la tentative de conciliation, A._ a, le 5 juillet 2017, saisi le Tribunal civil des Montagnes et du Val-de-Ruz d'une demande à l'encontre de B._, tendant au paiement d'une indemnité correspondant à quatre mois de salaire, soit 28'106 fr.20 avec intérêts, à titre d'indemnité pour résiliation abusive du contrat de travail.
Par jugement du 13 novembre 2018, le tribunal a rejeté la demande.
Par arrêt du 16 avril 2019, la Cour d'appel civile du canton de Neuchâtel a rejeté pour l'essentiel l'appel de l'employée. Le motif du licenciement résidait dans le fait que l'employée avait entretenu un lien avec un ou des détenus par le biais d'un téléphone portable; elle avait en outre caché, pendant près de deux ans, à ses supérieurs le fait d'avoir eu des contacts avec un détenu et, par là-même, la présence d'objets prohibés dans l'enceinte de la prison. Elle avait ainsi porté un coup fatal au lien de confiance qui devait exister entre elle et son employeur. Ce motif n'était pas abusif, pas plus que la manière dont le congé avait été donné. En revanche, c'est à tort que les premiers juges avaient octroyé des dépens à B._ qui avait procédé par l'entremise de son service juridique.
C.
A._ interjette un recours en matière civile. Elle conclut à l'annulation de l'arrêt cantonal et du jugement de première instance, puis, principalement, au renvoi de la cause à la Cour d'appel civile, respectivement au Tribunal civil pour nouvelle décision et, subsidiairement, à la condamnation de B._ au paiement de la somme nette de 28'106 fr.20 avec intérêts. Encore plus subsidiairement, elle demande, en modification du chiffre 4 du dispositif de l'arrêt attaqué, l'allocation d'une indemnité de dépens de 476 fr.70 à la charge de B._.
Dans sa réponse, l'intimé conclut au rejet du recours.
Pour sa part, la cour cantonale renvoie aux considérants de son arrêt.

Considérant en droit :
1.
Les conditions de recevabilité du recours en matière civile sont réalisées sur le principe, notamment sous l'angle de la valeur litigieuse minimale de 15'000 fr. fixée pour les contestations de droit du travail (<ref-law>) ainsi que du délai pour recourir (<ref-law>).
De nature purement cassatoire, la conclusion principale de la recourante ne serait recevable que si la cour de céans venait à lui donner raison sous l'angle de la violation de son droit d'être entendue (<ref-ruling> consid. 1.3 p. 383; <ref-ruling> consid. 3.1 p. 489 s.). En tout état de cause, la conclusion subsidiaire du recours est de nature réformatoire, ce qui permet l'entrée en matière. Demeure réservé l'examen des griefs particuliers.
2.
2.1. Le recours en matière civile peut être exercé pour violation du droit fédéral (<ref-law>), y compris le droit constitutionnel (<ref-ruling> consid. 2.1 p. 247; <ref-ruling> consid. 2.4 p. 313). Le Tribunal fédéral applique le droit d'office (<ref-law>). Il n'est donc limité ni par les arguments soulevés dans le recours, ni par la motivation retenue par l'autorité précédente; il peut admettre un recours pour un autre motif que ceux qui ont été invoqués et il peut rejeter un recours en adoptant une argumentation différente de celle de l'autorité précédente (<ref-ruling> consid. 2 p. 89; <ref-ruling> consid. 1.3 p. 336; <ref-ruling> consid. 1.4; <ref-ruling> consid. 1.4 p. 400). Compte tenu de l'exigence de motivation contenue à l'art. 42 al. 1 et 2 LTF, sous peine d'irrecevabilité (<ref-law>), le Tribunal fédéral n'examine en principe que les griefs invoqués, sauf en cas d'erreurs juridiques manifestes. Il n'est pas tenu de traiter, comme le ferait une autorité de première instance, toutes les questions juridiques qui se posent, lorsque celles-ci ne sont plus discutées devant lui (<ref-ruling> consid. 2, 115 consid. 2; <ref-ruling> consid. 1.3). Par exception à la règle selon laquelle il applique le droit d'office, il n'examine la violation d'un droit constitutionnel que si le grief a été invoqué et motivé de façon détaillée (<ref-law>; <ref-ruling> consid. 2.3; <ref-ruling> consid 1.3; <ref-ruling> consid. 1.4 in fine).
2.2. Le Tribunal fédéral statue sur la base des faits établis par l'autorité précédente (<ref-law>). Il ne peut rectifier ou compléter les constatations de l'autorité précédente que si elles sont manifestement inexactes ou découlent d'une violation du droit au sens de l'<ref-law> (<ref-law>). «Manifestement inexactes» signifie ici «arbitraires» (<ref-ruling> consid. 1.3.1 p. 253; <ref-ruling> consid. 2 p. 117; <ref-ruling> consid. 1.5). Encore faut-il que la correction du vice soit susceptible d'influer sur le sort de la cause (<ref-law>).
La critique de l'état de fait retenu est soumise au principe strict de l'allégation énoncé par l'<ref-law> (<ref-ruling> consid. 2.3 p. 266 et les références). La partie qui entend attaquer les faits constatés par l'autorité précédente doit expliquer clairement et de manière circonstanciée en quoi ces conditions seraient réalisées (<ref-ruling> consid. 1.3.1 p. 18 et les références). Si elle souhaite obtenir un complètement de l'état de fait, elle doit aussi démontrer, par des renvois précis aux pièces du dossier, qu'elle a présenté aux autorités précédentes en conformité avec les règles de procédure les faits juridiquement pertinents à cet égard et les moyens de preuve adéquats (<ref-ruling> consid. 2 p. 90). Si la critique ne satisfait pas à ces exigences, les allégations relatives à un état de fait qui s'écarterait de celui de la décision attaquée ne pourront pas être prises en considération (<ref-ruling> consid. 1.3.1 p. 18). Aucun fait nouveau ou preuve nouvelle ne peut être présenté à moins de résulter de la décision de l'autorité précédente (<ref-law>).
La recourante procède à un «rappel succinct des faits» qui, pour succinct qu'il se veut, ne s'étend pas moins sur trois pleines pages du mémoire. Et surtout, elle ne soulève à aucun moment le grief d'établissement arbitraire des faits. Dans la mesure où les faits présentés dans le recours s'écartent de l'état de fait de l'arrêt attaqué, il n'en sera pas tenu compte.
3.
3.1. Invoquant l'<ref-law> et l'art. 29 al. 2 Cst., la recourante se plaint tout d'abord d'une violation de son droit d'être entendue «comme corollaire au droit à la preuve et un défaut de motivation». Elle explique ce qui suit: dans sa demande en paiement, elle aurait requis l'audition de quatorze témoins, dont douze n'auraient pas été entendus; le premier juge aurait partiellement écarté sa requête lors de l'audience du 24 janvier 2018, non sans indiquer que sa décision serait motivée dans le jugement à venir; la motivation promise ferait toutefois défaut dans le jugement final.
3.2. Dans la mesure où elle s'en prend au jugement de première instance, la recourante se trompe de cible: seul l'arrêt de la Cour d'appel civile est susceptible de recours. Les motifs qui ont conduit les juges cantonaux à écarter toute violation du droit à la preuve, respectivement toute violation de l'obligation de motiver du premier juge, peuvent en revanche être critiqués. La recourante n'y consacre toutefois qu'une partie marginale de son argumentation. Elle indique à ce propos: « ainsi, l'autorité intimée tombe dans l'arbitraire lorsqu'elle considère que la motivation contenue dans l'ordonnance de preuves était suffisante et que la recourante pouvait comprendre les raisons qui avaient poussé le premier juge à refuser l'administration de témoignages supplémentaires ».
La cour cantonale a considéré que le tribunal civil n'avait pas violé le droit d'être entendu de la recourante à l'issue du raisonnement suivant. Dans son ordonnance de preuves, le premier juge avait réservé les douze autres témoins proposés par la demanderesse «dès lors que les faits qu'ils sont censés prouver sont, a priori, sans pertinence avec les questions à résoudre (vague d'indignation chez le personnel, allégué 18), admis par le défendeur (la demanderesse a exercé ses fonctions durant près de deux ans sans remontrance ou manquement autre que celui qui est litigieux, cf. allégué 10, titre 7), ou encore susceptibles d'être éclaircis par les deux témoignages admis (allégués 4, 6, 7, 16 et 17) ». Cette motivation était suffisamment explicite, même si le premier juge avait indiqué qu'il motiverait son refus dans son jugement subséquent, ce qu'il a omis de faire. Il eût certes été préférable qu'il répète cet argumentaire dans son jugement, mais il n'a pas pour autant violé le droit d'être entendu de la recourante en omettant de le faire.
Si l'on comprend bien la recourante, en annonçant qu'il motiverait son refus dans le jugement final, le premier juge aurait laissé entendre qu'il se fonderait sur des motifs distincts de ceux qu'il avait déjà évoqués dans l'ordonnance de preuves. C'est faire preuve d'une bien curieuse logique. En réalité, s'il n'a rien indiqué d'autre dans le jugement final, il faut au contraire considérer qu'il s'en tenait aux motifs précédemment mentionnés dans l'ordonnance de preuves.
La recourante pouvait, au surplus, réitérer sa requête d'audition des témoins en question devant la Cour d'appel civile, ce qu'elle n'a pas manqué de faire. Les juges cantonaux ont toutefois écarté cette requête au motif que la recourante n'indiquait pas quels faits pertinents pourraient être établis à l'aide desdits témoins. La recourante se plaint de ce procédé en s'en référant en particulier aux pages 14 à 17 de son appel où elle aurait «expressément indiqué (...) les raisons pour lesquelles le jugement de première instance était incorrect et que toute éventuelle absence de preuve résultait du rejet infondé des témoins proposés». En réalité, on cherche vainement dans le passage indiqué l'énonciation précise des faits sur lesquels les témoins auraient dû, d'après la recourante, être auditionnés et il ne saurait être fait reproche aux juges cantonaux de ne pas s'être livrés à une exégèse de l'appel destinée à déterminer si, d'aventure, l'argumentation manquante ne pouvait pas être recomposée par des extraits prélevés ça et là, à l'instar d'un puzzle.
La cour cantonale n'a dès lors pas violé le droit d'être entendu - pas plus que le droit à la preuve - de la recourante.
4.
4.1. La recourante se plaint également de ce que les juges cantonaux auraient méconnu le caractère abusif de son licenciement. S'agissant du motif du congé, il appartenait, selon elle, à l'employeur de démontrer les faits qui lui étaient reprochés. Elle soutient en particulier ne pas avoir eu conscience de discuter avec un détenu. Or, l'employeur n'aurait pas prouvé que l'interlocuteur en question était un détenu. Sur ce point, il ne serait pas possible de se fonder sur les déclarations de l'employée lors de l'entretien du 24 août 2016, car elle aurait été interrogée seule par sa hiérarchie - soit le directeur et le surveillant-chef - et sans l'assistance d'un avocat, ce qui l'aurait placée dans l'impossibilité de défendre sa position. Par ailleurs, le licenciement aurait été formulé de manière à blesser la personnalité de l'employée et serait, également de ce fait, abusif.
4.2. Lorsque le contrat de travail est de durée indéterminée, chaque partie est en principe libre de le résilier (<ref-law>), moyennant le respect du délai et du terme de congé convenus ou légaux. Le droit suisse du contrat de travail repose en effet sur la liberté contractuelle. La résiliation ordinaire du contrat de travail ne suppose pas l'existence d'un motif de congé particulier (<ref-ruling> consid. 2.1; <ref-ruling> consid. 4.1; <ref-ruling> consid. 2a p. 88). La limite à la liberté contractuelle découle des règles de l'abus de droit (<ref-law>). La résiliation ordinaire du contrat de travail est abusive lorsqu'elle intervient dans l'une des situations énumérées à l'<ref-law>, lesquelles se rapportent aux motifs indiqués par la partie qui résilie (<ref-ruling> consid. 2.3 p. 514/515; <ref-ruling> consid. 2.4 p. 118; <ref-ruling> consid. 4.2 p. 539). L'énumération de l'<ref-law> n'est pas exhaustive et un abus du droit de résiliation peut se révéler aussi dans d'autres situations qui apparaissent comparables, par leur gravité, aux hypothèses expressément visées par cette disposition (<ref-ruling> consid. 2.3 p. 514/515; <ref-ruling> consid. 2 p. 116; <ref-ruling> consid. 4 p. 537). Ainsi, la résiliation ordinaire est abusive lorsque l'employeur la motive en accusant le travailleur d'un comportement contraire à l'honneur, s'il apparaît que l'accusation est infondée et que, de plus, l'employeur l'a élevée sans s'appuyer sur un indice sérieux ni avoir entrepris de vérification (arrêts 4A_485/2016-4A_491/2016 du 28 avril 2017 consid. 2.2.2; 4A_694/2015 du 4 mai 2016 consid. 2.2; 4A_99/2012 du 30 avril 2012 consid. 2.2.1). La manière dont le congé est donné peut aussi le faire apparaître comme abusif. Même lorsque le motif de la résiliation est en soi légitime, celui qui exerce son droit de mettre fin au contrat doit agir avec des égards. Si l'employeur porte une grave atteinte à la personnalité du travailleur dans le contexte d'une résiliation, celle-ci doit être considérée comme abusive; un comportement simplement inconvenant ne suffit pas (<ref-ruling> consid. 2.2 p. 117 et consid. 2.3 p. 118; <ref-ruling> consid. 4.2 p. 538 s.).
Pour pouvoir examiner si la résiliation ordinaire est abusive ou non (<ref-law>), il faut déterminer quel est le motif de congé invoqué par la partie qui a résilié (<ref-ruling> consid. 2 p. 116; <ref-ruling> consid. 4 p. 537; <ref-ruling> consid. 2 p. 72). Le motif de la résiliation relève du fait (<ref-ruling> consid. 4.1 p. 702 s.) et les constatations de l'arrêt attaqué à ce sujet ne peuvent être attaquées que dans la mesure restreinte permise par l'<ref-law>, à savoir pour arbitraire (art. 9 Cst.) dans l'établissement des faits et l'appréciation des preuves. En revanche, savoir si le motif ainsi établi donne lieu à un congé abusif ou non relève de l'application du droit, que le Tribunal fédéral revoit librement.
Il incombe en principe au destinataire de la résiliation de démontrer que celle-ci est abusive. Le juge peut toutefois présumer en fait l'existence d'un congé abusif lorsque l'employé parvient à présenter des indices suffisants pour faire apparaître comme non réel le motif avancé par l'employeur. Ce dernier ne peut alors rester inactif, n'ayant d'autre issue que de fournir des preuves à l'appui de ses propres allégations quant au motif de congé (<ref-ruling> consid. 4.1 p. 703; <ref-ruling> consid. 4b).
4.3. Il est constant que les parties se sont liées par un contrat de travail de durée indéterminée, librement résiliable par chacune d'elles conformément à l'<ref-law>, moyennant le respect du délai et du terme de congé convenus ou légaux.
Le principal motif invoqué par l'employeur à l'appui du congé ordinaire réside dans les contacts téléphoniques entretenus par l'employée avec un ou des détenus. En droit, l'absence de caractère abusif d'un tel motif n'est guère contestable. La recourante reproche à tort à l'employeur de ne pas avoir apporté la preuve de la réalité de ce motif. Il ne lui appartenait pas de le faire: c'était à elle, bien au contraire, de démontrer que les faits reprochés ne s'étaient pas produits.
La cour cantonale a jugé que cette preuve n'avait pas été apportée. Bien plus, fondés sur les propres déclarations de la recourante transcrites dans le procès-verbal du 24 août 2016, les juges neuchâtelois ont retenu que les contacts téléphoniques prohibés avaient bel et bien eu lieu. Il s'agit là d'une problématique de constatation de faits et d'appréciation des preuves que le Tribunal fédéral ne pourrait revoir que s'il était saisi du grief d'arbitraire. Ce n'est toutefois pas sous cet angle que la recourante déploie son argumentation. Elle se borne à prétendre que ses déclarations lors de l'entrevue du 24 août 2016 telles que protocolées ne suffiraient pas à attester qu'elle savait qu'elle conversait avec un détenu lors des contacts en cause, tirant argument de "l'exploitation du lien de subordination" et la "situation de faiblesse et d'infériorité" dans laquelle elle aurait été placée. La recourante n'évoque toutefois aucun élément de fait qui accréditerait cette assertion. Selon elle, le procès-verbal de l'entretien n'en refléterait pas fidèlement la teneur. Il n'a pourtant pas été signé sur le vif, mais le lendemain de la rencontre. La recourante se plaint encore de "l'attitude de sa hiérarchie" à cette occasion, mais - derechef - n'évoque pas le moindre élément susceptible de décrire dans quelle mesure cette attitude aurait été inappropriée. C'est finalement à tort que la recourante se prévaut d'une situation analogue à celle qui a fait l'objet de l'arrêt 4A_694/2015 précité. Le 17 août 2016 déjà, le directeur de l'établissement s'est approché de l'employée de manière informelle afin de lui demander si les identifiants «Skype» décelés lui appartenaient; les soupçons pesant contre elle ont également été évoqués à cette occasion. Les thèmes abordés lors de l'entrevue du 24 août 2016 ne représentaient dès lors pas une surprise pour l'employée et, si elle l'avait estimé nécessaire, elle aurait pu s'adjoindre un mandataire professionnel. Il n'appartenait en revanche pas à l'employeur - fût-il représenté par deux personnes lors de cet entretien - de lui conseiller de le faire, comme elle le soutient à mots couverts.
S'agissant de la manière dont le licenciement lui a été signifié, la recourante y voit également un abus du droit de l'employeur. Cela étant, si l'on peut fort bien concevoir que le congé ait bouleversé l'employée, que celle-ci ait dû consulter un médecin à la suite de ces événements et que le licenciement la plaçait dans la situation de devoir retrouver un emploi - avec le lot de soucis qui l'accompagnait -, l'employeur n'en porte pas la responsabilité. Il n'a selon toute évidence pas licencié l'employée pour la blesser, comme celle-ci le suggère plus qu'elle ne l'affirme. La recourante colore la réalité lorsqu'elle évoque ne pas avoir été en mesure de récupérer ses affaires personnelles avant le terme de son contrat de travail - dès lors qu'elle n'avait plus accès aux locaux de l'établissement de détention - et ne pas avoir pu saluer ses collègues. On ne discerne aucune intention malveillante de la part de l'employeur dans ces faits, lesquels ne sont au demeurant pas établis, pas plus du reste que les rumeurs au sujet des motifs du licenciement que l'intimé aurait prétendument laissé se propager et dont la teneur n'est même pas évoquée.
C'est dès lors à bon droit que la cour cantonale a considéré que le congé n'était pas abusif.
5.
Enfin, la recourante - au terme de conclusions encore plus subsidiaires, dont le caractère demeure inexpliqué - réclame l'allocation de dépens de seconde instance d'un montant de 476 fr.70 pour avoir obtenu gain de cause sur la question des dépens que le premier juge avait alloués à tort à B._
L'<ref-law> pose le principe que les frais - frais judiciaires et dépens (<ref-law>) - sont à la charge de la partie qui succombe. Lorsqu'aucune des parties n'obtient entièrement gain de cause, les frais sont répartis selon le sort de la cause (<ref-law>). Cette réglementation accorde au juge un large pouvoir d'appréciation en matière de répartition des frais (arrêt 4A_207/2015 du 2 septembre 2015 consid. 3.1 et l'arrêt cité).
Si l'on considère l'intérêt pécuniaire attaché à chacun des griefs qu'elle avait soulevés en appel, il apparaît à l'évidence que la recourante n'a obtenu gain de cause que sur un point minime, de sorte qu'il pouvait demeurer sans incidence sur la fixation des dépens (DENIS TAPPY, in Commentaire romand, Code de procédure civile, 2 e éd. 2019, n° 16 ad <ref-law>; RÜEGG/RÜEGG, in Basler Kommentar, Schweizerische Zivilprozessordnung, 3 e éd. 2017, n° 3 ad <ref-law>). Les juges cantonaux n'ont dès lors pas abusé de leur pouvoir d'appréciation en renonçant à une répartition selon l'<ref-law>.
6.
Sur le vu de ce qui précède, le recours doit être rejeté.
En conséquence, les frais judiciaires - fixés selon le tarif réduit (art. 65 al. 4 let. c LTF) - seront mis à la charge de la recourante (<ref-law>). Il n'est pas alloué de dépens à l'intimé, qui a procédé sans être représenté par un avocat.

Par ces motifs, le Tribunal fédéral prononce :
1.
Le recours est rejeté.
2.
Les frais judiciaires, arrêtés à 1'000 fr., sont mis à la charge de la recourante.
3.
Le présent arrêt est communiqué aux parties et à la Cour d'appel civile du Tribunal cantonal du canton de Neuchâtel.
Lausanne, le 9 janvier 2020
Au nom de la Ire Cour de droit civil
du Tribunal fédéral suisse
La Présidente : Kiss
La Greffière : Godat Zimmermann